﻿#ifndef PST_CENTERWIDGET_H
#define PST_CENTERWIDGET_H

#include <QWidget>
#include "InfomationCurve2DBasical.h"
#include "InfomationGraph3DBasical.h"
#include "TableChatWindow.h"
#include "PostEnumType.h"
#include "parser/JsonDef.h"
#include <optional>

QT_BEGIN_NAMESPACE
namespace Ui
{
    class CenterWidget;
};

class QTabWidget;
class QTreeView;
class QStandardItem;
QT_END_NAMESPACE

namespace pst
{
    class Graph2DWindowBase;
    class Graph3DWindowBase;
    // class GraphSurface;
    class AnimationSettingData;
    class HeatMapWindow;
    class ThreeDSurfacePlotWindow;
    class ThreeDCloudMapWindow;
    class SurfaceElectricFieldMapWindow;
    class LineChartWindow;
    class PolarCoordinateGraphWindow;

    /// @brief 中心视图 管理工程树，tab标签（每个标签是一个后处理窗口）
    class CenterWidget : public QWidget
    {
        Q_OBJECT
    public:
        Q_INVOKABLE explicit CenterWidget(QWidget* parent = nullptr);
        void on_tabWidget_tabCloseRequested(int index);
        void on_tabWidget_tabClicked(int index);
        ~CenterWidget();

        QWidget* getCurrentGraphWindow();

        void showContextMenu(const QPoint& pos);

        void clearData();
        void addToCurrentGraph();

        // void addNewProject();
        /// @brief 工程树添加节点
        /// @param item 添加的节点
        /// @param isImprotData 是否是导入数据，当使用导入数据功能时添加的节点，选中当前节点
        void addFileNode(QStandardItem* item, bool isImprotData = false);
        // 是否设置添加新窗口后自动设置为当前展示窗口
        void setAddedGraphWindowActiveAuto(bool activeAuto);
        bool getAddedGraphWindowActiveAuto();

        void addLineToGrapg2D(Graph2DWindowBase* _graph2D, const QPair<QString, QVector<double>>& x, const QPair<QString, QVector<double>>& y);

        void addImageToGrapg2D(Info2DPointer& info);

        void addImageToNewGrapg2DWindow(QList<Info2DPointer>& infos, bool useNewWindow);

        // 2D graph管理
        Graph2DWindowBase* addNewGraph2D(GraphType type, int windowUniversalID = -1, int windowID = -1);//当windowUniversalID有值时为打开项目调用

        QTreeView* getTreeView() const;

        QTabWidget* getTabWidget();

        // 3D graph管理
        Graph3DWindowBase* addNewGraph3D(GraphType type, int windowUniversalID = -1, int windowID = -1);//当windowUniversalID有值时为打开项目调用
        /// @brief 一个三维窗口添加多个图
        void addImageToGraph3DWindow(QList<InfomationGraph3DBasical*>& infos, bool useNewWindow);
        void addImageToGraph3D(InfomationGraph3DBasical* info);

        Graph3DWindowBase* getGraph3DWindowBaseByUniversalID(int windowUniversalID);

        // graph surface 管理
        // GraphSurface* addNewGraphSurface();
        // void addImageToNewSurfaceWindow(const QString& fileName);

        // 展示到表格
        void addDataToTableWindow(InfomationGraph3DBasical* infos, bool useNewWindow, int windowUniversalID = -1, int windowID = -1);//当windowUniversalID有值时为打开项目调用

        // void setCurrentTab(Graph2D* _graph2D);
        QList<QStandardItem*> getSelectedItems();

        AnimationSettingData* getAnimationSettingData() const;

        /// @brief 设置项目树右键时可以添加到右键菜单的项
        void setFileTypeList(QList<bool> list);

        // void showModel(bool isShow);
        // 设置工程树的状态
        void setTreeViewState(bool isEnabled);
        // 获取item深度
        int getItemDepth(const QStandardItem* item);
        // 获取子树成员
        QList<QStandardItem*> getSubtreeByItem(const QStandardItem* item);
        // 获取leafs
        QList<QStandardItem*> getLeafsByItem(const QStandardItem* item);
        // 深度拷贝节点
        QStandardItem* deepCopyItem(const QStandardItem* item, const std::function<void(QStandardItem* copied, const QStandardItem* original)>& onCopy);
        // 获取粘贴后的节点名称
        QString getPasteItemText(const QStandardItem* item, const QStandardItem* parent);
        // py table start
        void pyHideOrShowTableColumn(int windowId, QString selectedIndex);
        void pyChangeTbColumnName(int windowId, int index, QString newName);
        void pyFlushTbBySelectedRow(int windowId, QString parms);
        void pyExportTbData(int windowId, QString filePath, QString delimiter, int onlyVisible);
        void pyHighlightSelectedTbColumns(int windowId, QString parms);
        TableChatWindow* getTableChatWindowByWindowId(int windowId);
        // py table end

        void pyDoPrjCloseTree(int index);
        void pyDoPrjTreeCopyDir(int index);
        void pyDoPrjTreePasteDir(int srcId, int destId);
        void pyDoPrjTreeCopyData(int index);
        void pyDoPrjTreePasteData(int srcId, int destId);
        void pyDoPrjTreeExpandDir(int index);
        void pyDoPrjTreeCollapseDir(int index);
        void pyCloseCenterTableBar(int index);
        void pyChangeCurrentTabBar(int index);

        void pySubmitEvaluation(int windowId, int evaluationType, QString parms);

    signals:
        void signal_fileClicked(const QList<QStandardItem*>& indexs);
        void signal_addToCurrentGraph(const QList<QStandardItem*>& indexs);
        void signal_currentWindowChanged();

        void signal_displayNew2DGraph(FileDataType type, bool isOpenNewWindow);
        void signal_displayNewSurfaceElectricFieldGraph(bool isOpenNewWindow);
        void signal_displayNewThreeDCloudMap(bool openNewWindow);
        void signal_displayNewThreeDSurfacePlot(bool isOpenNewWindow);
        void signal_displayInTableWidget();
        void signal_getTwoDResultDataPointer(const TextFileParser* textFIleParser, ResultDataPointer& resultDataPointer);
        void signal_updateMeasureButtonState(int state);
        void signal_updateStandardCcurveState(bool state);
        void signal_pasteFile(QStandardItem* copyFileItem, QStandardItem* pasteFileItem);

        

    private:
        /// @brief 初始化链接信号槽
        void initConnect();
        /// @brief 添加展开和折叠节点的动作
        /// @param contextMenu
        /// @param item
        void addFoldingAction(QMenu& contextMenu, QStandardItem* item);

        HeatMapWindow* getHeatMapWindowByWindowID(int windowID);
        PolarCoordinateGraphWindow* getPolarCoordinateGraphWindowByWindowID(int windowID);
        LineChartWindow* getLineChartWindowByWindowID(int windowID);
        ThreeDSurfacePlotWindow* getThreeDSurfacePlotWindowByWindowID(int windowID);
        ThreeDCloudMapWindow* getThreeDCloudMapWindowByWindowID(int windowID);
        SurfaceElectricFieldMapWindow* getSurfaceElectricFieldMapWindowByWindowID(int windowID);

        void traverseTreeView(QModelIndex& parent, int depth);
        void saveCollapseOrExpandPyCode(bool expand, int itemId);

        void closeCenterTableBar(int index, bool savePy);
        void changeCurrentTabBar(int index, bool savePy);

    public slots:

        /// @brief 粘贴单个节点数据
        void slot_pasteFileItemData(int srcItemID, int TargetItemID);
        /// @brief 粘贴文件夹数据
        /// @param srcItemID 源文件夹ID
        /// @param TargetItemID 目标文件夹ID
        void slot_pasteDirectoryItemData(int srcItemID, int TargetItemID);
        // void slot_fileClicked(const QModelIndex& index);
        void slot_addImageToNewGrapg2DWindow(QList<Info2DPointer>& infos);

        void slot_projectTreeSelectionChanged(QList<int> projectTreeSelctedRowIDList, bool* isSuccess);
        void slot_saveScreenShot(const QString& path, bool* isSuccess);
        void slot_setHeatMapSelectedCurveNameIndexs(int windowId, QList<int> selectedCurveNameIndexs);
        void slot_setHeatMapVariableAxisChanged(int windowId, int variableAxisIndex);
        void slot_setHeatMapFixedValueChanged(int windowId, QList<int> indexList);
        void slot_setHeatMapComplexPartsChanged(int windowId, bool isAmplitudeChecked, bool isPhaseChecked, bool isRealPartChecked, bool isImaginaryPartChecked);
        void slot_setHeatMapSecondVariableAxisChanged(int windowId, int variableAxisIndex);
        void slot_setHeatMapCurveNameCheckStateChanged(int windowId, int curveNameIndex, bool checkState);
        void slot_setHeatMapDataOprationChanged(int windowId, bool isLoged, bool isNormalized);
        void slot_setHeatMapResultValueDataChanged(int windowId, int index);
        void slot_saveHeatMapMainSettingData(int windowId, bool scalarBarIsAutoRange, double scalarBarMin, double scalarBarMax,
                                             QString scalarBarColor, int scalarBarFontSize, bool XAxisAutoTitle, QString XAxisTitle, QString XTitleFontColor, int XTitleFontSize,
                                             QString XAxisColor, double XAisThickness, int XValuePrecision, QString XAxisDigitColor, int XAxisDigitSize,
                                             bool XAxisIsAutoRange, double XAxisMax, double XAxisMin, bool XIsAutoStepSize, double XCustomStepSize,
                                             bool YAxisAutoTitle, QString YAxisTitle, QString YTitleFontColor, int YTitleFontSize,
                                             QString YAxisColor, double YAisThickness, int YValuePrecision, QString YAxisDigitColor, int YAxisDigitSize,
                                             bool YAxisIsAutoRange, double YAxisMax, double YAxisMin, bool YIsAutoStepSize, double YCustomStepSize,
                                             bool gridIsMainGridLineDisplay, QString gridMainGridLineColor, int gridMainGridLineStyle, double gridMainGridLineThickness,
                                             bool gridIsSecondaryGridLineDisplay, QString gridSecondaryGridLineColor, int gridSecondaryGridLineStyle, double gridSecondaryGridLineThickness,
                                             QString windowTitleName, QString windowTitleFontColor, int windowTitleFontSize);
        void slot_setHeatMapRemoveSelectedGraph(int windowId);
        void slot_setHeatMapRenameFinished(int windowId, QString name);
        void slot_setHeatMapAddTracer(int windowId, QString name, double x, double y, double value, int tracerStyle, int size, int penR, int penG, int penB, int penA, int interpolating, int curveInfoID, int tracerIndex);
        void slot_setHeatMapRemoveSelectedTracer(int mainWindowId, QList<int> infoIdList);
        void slot_setHeatMapRemoveAllTracer(int mainWindowId, QList<int> infoIdList);
        void slot_setHeatMapExportMarkerData(int windowId, QString fileName);
        void slot_setHeatMapChangeTracerProperty(int mainWindowId, QString name, int symbolStyle, int size, int penR, int penG, int penB, int penA, int tracerID);

        // 二维折线图
        void slot_lineChartSidebarVariableAxisChanged(int mainWindowId, QList<int> allSelectedItem, int reuslt, QString sVariableAxistCurrentText);
        void slot_lineChartSidebarCurveNameClicked(int mainWindowId, QList<int> allSelectedItemIndexList);
        void slot_lineChartSidebarCurveNameCheckStateChanged(int mainWindowId, int index, int checkStatus);
        void slot_lineChartSidebarFixedValueChanged(int mainWindowId, QList<int> allIndexLis);
        void slot_lineChartSidebarDataOperationChanged(int mainWindowId, bool isNormChecked, bool isDBChecked, bool isMathOperationChecked);
        void slot_lineChartSidebarValueDataChanged(int mainWindowId, int currentIndex);
        void slot_lineChartSaveMainSettingData(int mainWindowId, int index,
                                               bool axiDisIsAutoName, QString axiDisTitleText, QString axiDisTitleFontColorStr, int axiDisTitleFontSize, QString axiDisAxisColorStr, int axiDisAxisThickness, double axiDisValuePrecision, QString axiDisAxisDigitColorStr, int axiDisAxisDigitSize,
                                               bool axiRangIsAutoRange, double axiRangMaxValue, double axiRangMinValue, bool axiRangIsAutoStepSize, double axiRangCustomStepSize,
                                               bool yAxiDisIsAutoName, QString yAxiDisTitleText, QString yAxiDisTitleFontColorStr, int yAxiDisTitleFontSize, QString yAxiDisAxisColorStr, int yAxiDisAxisThickness, double yAxiDisValuePrecision, QString yAxiDisAxisDigitColorStr, int yAxiDisAxisDigitSize,
                                               bool yAxiRangIsAutoRange, double yAxiRangMaxValue, double yAxiRangMinValue, bool yAxiRangIsAutoStepSize, double yAxiRangCustomStepSize,
                                               bool gridIsMainGridLineDisplay, QString gridMainGridLineColorStr, int gridMainGridLineStyle, double gridMainGridLineThickness, bool gridIsSecondaryGridLineDisplay, QString gridSecondaryGridLineColorStr, int gridSecondaryGridLineStyle, double gridSecondaryGridLineThickness,
                                               QString titleName, QString titleFontColorStr, int titleFontSize,
                                               QString legendFontColorStr, int legendFontSize, QString legendLineColorStr, int legendLineThickness,
                                               QString resultDataName, QString dataLineColorStr, int dataLineStyle, double dataLineThickness, bool isDisplaySymbol, int symbolStyle, double symbolSize, QString symbolColorStr);
        void slot_lineChartWindowAddTracer(int windowUniversalID, QString parameters);

        // 极坐标图
        void slot_polarCoordinateGraphSidebarVariableAxisChanged(int mainWindowId, QList<int> allSelectedItem, int reuslt, QString sVariableAxistCurrentText);
        void slot_polarCoordinateGraphSidebarAllVariableAxisChanged(int mainWindowId, QString sVariableAxistCurrentText);
        void slot_polarCoordinateGraphSidebarCurveNameClicked(int mainWindowId, QList<int> allSelectedItemIndexList);
        void slot_polarCoordinateGraphSidebarCurveNameCheckStateChanged(int mainWindowId, int index, int checkStatus);
        void slot_polarCoordinateGraphSidebarDataOperationChanged(int mainWindowId, bool isNormChecked, bool isDBChecked);
        void slot_polarCoordinateGraphSidebarValueDataChanged(int mainWindowId, int currentIndex);
        void slot_polarCoordinateGraphSidebarDeleteAllGraph(int mainWindowId);
        void slot_polarCoordinateGraphSidebarRenameSelectedGraph(int mainWindowId, QString name);
        void slot_polarCoordinateGraphSidebarComplexPartsChanged(int windowId, bool isAmplitudeChecked, bool isPhaseChecked, bool isRealPartChecked, bool isImaginaryPartChecked);
        void slot_polarCoordinateGraphSidebarFixedValueChanged(int windowId, QList<int> indexList);
        void slot_polarCoordinateGraphSidebarRemoveSelectedGraph(int windowId, QList<int> indexList);
        void slot_polarCoordinateGraphSidebarCopySelectedGraph(int windowId);
        void slot_polarCoordinateGraphSaveMainSettingData(int mainWindowId, int index, QString angDisAxisColor, int angDisAxisThickness, double angDisValuePrecision, QString angDisAxisDigitColor, int angDisAxisDigitSize,
                                                          bool angRangIsAutoStepSize, double angRangCustomStepSize,
                                                          QString radDisAxisColorStr, int radDisAxisThickness, double radDisValuePrecision, QString radDisAxisDigitColorStr, int radDisAxisDigitSize,
                                                          bool radRangIsAutoRange, double radRangMaxValue, double radRangMinValue, bool radRangIsAutoStepSize, double radRangCustomStepSize,
                                                          bool gridIsMainGridLineDisplay, QString gridMainGridLineColor, int gridMainGridLineStyle, double gridMainGridLineThickness,
                                                          QString titleName, QString titleFontColor, int titleFontSize,
                                                          QString legendFontColor, int legendFontSize, QString legendLineColor, int legendLineThickness,
                                                          QString dataProResultDataName, QString dataProDataLineColor, int dataProDataLineStyle, double dataProDataLineThickness, bool dataProIsDisplaySymbol, int dataProSymbolStyle, double dataProSymbolSize, QString dataProSymbolColor);

        void slot_polarCoordinateGraphAddTracer(int mainWindowId, QString name, double angle, int tracerStyle, int size, int penR, int penG, int penB, int penA,
                                            int brushR, int brushG, int brushB, int brushA, int interpolating, int curveInfoID, int tracerIndex);
        void slot_polarCoordinateGraphRemoveSelectedTracer(int windowId, QList<int> infoIdList, int curveInfoID);
        void slot_polarCoordinateGraphRemoveAllTracer(int windowId, QList<int> infoIdList);
        void slot_polarCoordinateGraphExportMarkerData(int windowId, QString fileName);
        void slot_polarCoordinateGraphChangeTracerProperty(int mainWindowId, QString name, double x, int symbolStyle, int size, int penR, int penG, int penB, int penA, int tracerID);

        // 三维曲面图
        void slot_threeDSurfacePlotSidebarCurveNameClicked(int windowId, QList<int> selectedIndexes);
        void slot_threeDSurfacePlotSidebarFrequencyChanged(int windowId, int frequencyId);
        void slot_threeDSurfacePlotSidebarResultDataChanged(int windowId, int resultDataIndex);
        void slot_threeDSurfacePlotSidebarDataOprationChanged(int windowId, bool isLoged, bool isNormalized);
        void slot_threeDSurfacePlotSidebarCurveNameItemCheckStateChanged(int windowId, int itemIndex, bool checkState);
        void slot_saveThreeDSurfacePlotMainSettingData(int windowId, int settingDataId, bool scalarBarIsAutoRange, double scalarBarMin, double scalarBarMax,
                                                       bool scalarBarIsShowTitle, QString scalarBarTitle, QString scalarBarFontColor, int scalarBarFontSize, int geometryTransparency,
                                                       QString resultGraphName, int resultGraphModelTransparency, double resultGraphScale, bool cubeAxesIsVisible);
        void slot_saveThreeDSurfacePlotMoveResultDataSetting(int windowId, int infomationId, double translationX, double translationY, double translationZ,
                                                             double rotationTheta, double rotationPhi);
        void slot_delete3DSurfacePlots(int windowId, QString selectedIndexs);
        void slot_threeDSurfaceCurveNameItemRename(int windowId, int itemIndex, QString newName);
        void slot_threeDSurfaceCurveDataFileterRadioButtonClicked(int windowId, int index);

        // 三维云图
        void slot_threeDCloudMapSidebarCurveNameClicked(int windowId, QList<int> selectedIndexes);
        void slot_threeDCloudMapSidebarUpdateFixedParameter(int windowId, int index);
        void slot_threeDCloudMapSidebarUpdateOriginalDataSource(int windowId, int index, int showType, int fixedValueIndex, bool isLog, bool isNormalize);
        void slot_threeDCloudMapSidebarResultDataChanged(int windowId, int index);
        void slot_threeDCloudMapSidebarNameItemRename(int windowId, int itemIndex, QString newName);
        void slot_threeDCloudMapSidebarDelete3DCloudMap(int windowId, QString selectedIndexs);
        void slot_threeDCloudMapSidebarDataOprationChanged(int windowId, bool isLoged, bool isNormalized);
        void slot_threeDCloudMapSidebarItemCheckStateChanged(int windowId, int itemIndex, bool visible);
        void slot_saveThreeDCloudMapMainSettingData(int windowId, int type, int settingDataId, bool scalarBarIsAutoRange,
                                                    double scalarBarMin, double scalarBarMax, bool scalarBarIsShowTitle,
                                                    QString scalarBarTitle, QString scalarBarFontColor, int scalarBarFontSize,
                                                    int geometryTransparency, QString resultGraphName, int resultGraphModelTransparency, bool cubeAxesIsVisible);

        // 表面电场图
        void slot_surfaceElectricFieldMapSidebarCurveNameClicked(int windowId, QList<int> selectedIndexes);
        void slot_surfaceElectricFieldMapSidebarResultDataChanged(int windowId, int index);
        void slot_surfaceElectricFieldMapSidebarUpdateProcessData(int windowId, bool isLog, bool isNormalize);
        void slot_surfaceElectricFieldMapSidebarNameItemRename(int windowId, int itemIndex, QString newName);
        void slot_surfaceElectricFieldMapSidebarDeleteSurfaceElectricFieldMap(int windowId, QString selectedIndexs);
        void slot_surfaceElectricFieldMapSidebarItemCheckStateChanged(int windowId, int itemIndex, bool visible);
        void slot_saveSurfaceElectricFieldMapMainSettingData(int windowId, int type, int settingDataId, bool scalarBarIsAutoRange,
                                                             double scalarBarMin, double scalarBarMax, bool scalarBarIsShowTitle,
                                                             QString scalarBarTitle, QString scalarBarFontColor, int scalarBarFontSize,
                                                             int geometryTransparency, QString resultGraphName, int resultGraphModelTransparency, bool cubeAxesIsVisible);

        // 三维图标记
        void slot_savePostMarkerAddSettingData(int windowUniversalID, int infomationGraph3DBasicalId, int type,
                                               int fieldIndex, QString fieldName, int pickedId, QString pickedValue);
        void slot_savePostMarkerRemoveChosenSettingData(int windowUniversalID, QString removeChosenId);
        void slot_savePostMarkerRemoveAllSettingData(int windowUniversalID);
        void slot_savePostMarkerExportTableData(int windowUniversalID, QString fileName);

        void slot_sentWaveButterANdFFTVResult(int windowId, const QList<double>& resultList);

    private:
        Ui::CenterWidget* ui;
        /// @brief 左侧项目树
        // QTreeView* m_treeView{ nullptr };
        /// @brief 右侧的后处理窗口
        // QTabWidget* m_tabWidget{ nullptr };
        // Graph2D* _graph2D;

        QList<Graph2DWindowBase*> m_graph2DList;
        bool m_isActiveAuto{true};
        int m_graph2DCount{0};
        QList<Graph3DWindowBase*> m_graph3DList;
        QHash<QString, int> m_tabNameNum;

        AnimationSettingData* m_animationSettingData;

        QList<QPair<int, HeatMapWindow*>> m_heatMapWindowList;

        QList<QPair<int, PolarCoordinateGraphWindow*>> m_polarCoordinateGraphWindowList;

        QList<QPair<int, LineChartWindow*>> m_lineChartWindowList;

        QList<QPair<int, ThreeDSurfacePlotWindow*>> m_surfacePlotWindowList;

        QList<QPair<int, ThreeDCloudMapWindow*>> m_threeDCloudMapWindowList;

        QList<QPair<int, SurfaceElectricFieldMapWindow*>> m_surfaceElectricFieldMapWindowList;

        QList<QPair<int, TableChatWindow*>> m_tableWindowList;

        bool m_is2D = false;
        bool m_isPolar = false;
        bool m_isSurfaceElectricField = false;
        bool m_isTwoDHeatMap = false;
        bool m_isThreeDCloudMap = false;
        bool m_isThreeDSurfacePlot = false;
        bool m_TwoDPeakValleyGraph = false;
        bool m_isDataTable = false;

        /*
         * copy选中file项 info
         */
        struct CopyFileInfo
        {
            int depth;
            QStandardItem* item;
        };
        std::optional<CopyFileInfo> copyFileInfo;

        /*
         * copy选中dir项 info
         */
        struct CopyDirInfo
        {
            int depth;
            QStandardItem* item;
            QPersistentModelIndex persistentIndex;
        };
        std::optional<CopyDirInfo> copyDirInfo;

        /*
         * 拷贝的二维折线图info
         */
        QList<Info2DPointer> infoListLineChartCopy;

        QHash<int, QStandardItem*> m_treeItemMap;
        QStandardItemModel* treeModel;
        bool m_needFlushItemMap = false;
        bool m_isCanCloseTab = true;
    };

} // namespace pst
#endif // T_NAVIGATION_H
